

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import net.sf.json.JSONObject;

/**
 * 聊天服务器类
 * @author 朱宏亮
 *
 *@ServerEndpoint 注解是一个类层次的注解，它的功能主要是将目前的类定义成一个websocket服务器端。
 *注解的值将被用于监听用户连接的终端访问URL地址。
 *
 *onOpen 和 onClose 方法分别被 @OnOpen 和 @OnClose 所注解。
 *这两个注解的作用不言自明：他们定义了当一个新用户连接和断开的时候所调用的方法。
 *
 *onMessage 方法被 @OnMessage 所注解。
 *这个注解定义了当服务器接收到客户端发送的消息时所调用的方法。
 *注意：这个方法可能包含一个javax.websocket.Session可选参数（在我们的例子里就是session参数）。
 *如果有这个参数，容器将会把当前发送消息客户端的连接Session注入进去。
 *
 */
@ServerEndpoint("/websocket")
public class ChatServer {
	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");	// 日期格式化

	static Set<Session> users =  new CopyOnWriteArraySet<Session>();//把所有的session存在这个static集合里面
	
	@OnOpen
	public void open(Session session) {
		// 添加初始化操作
		users.add(session);
		System.out.println("当前用户数量："+users.size());
	}
	
	/**
	 * 接受客户端的消息，并把消息发送给所有连接的会话
	 * @param message 客户端发来的消息
	 * @param session 客户端的会话
	 */
	@OnMessage
	public void getMessage(String message, Session session) {
		//打印message
		System.out.println("当前用户发送信息："+message);
		System.out.println("当前用户sessionID:"+session.getId());
		
		// 把客户端的消息解析为JSON对象
		JSONObject jsonObject = JSONObject.fromObject(message);
		
		// 在消息中添加发送日期
		jsonObject.put("date", DATE_FORMAT.format(new Date()));
		
		// 把消息发送给所有连接的会话
		int i = 0 ;
		System.out.println("当前用户数量:"+users.size());
		for (Session openSession : users) {

			// 添加本条消息是否为当前会话本身发的标志
			jsonObject.put("isSelf", openSession.equals(session));
			
			// 发送JSON格式的消息
			openSession.getAsyncRemote().sendText(jsonObject.toString());
			
		}
	}

	@OnClose
	public void close(Session session) {
		// 添加关闭会话时的操作
		users.remove(session);
		System.out.println("用户已断开ID："+session.getId());
	}

	@OnError
	public void error(Throwable t, Session session) {
		// 添加处理错误的操作
		try{
			System.out.println("客户端断开连接");
			//close(session);
		}catch(Exception a){
			a.printStackTrace();
		}
	}
}